﻿package glam.skins;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.InteractiveObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.Lib;
import fpc.styles.skins.ButtonState;
import fpc.styles.skins.IFixedButtonSkin;
import fpc.utils.IFactory;
import glam.Primitives;

class GlamRadioButton implements IFactory<IFixedButtonSkin>
{
	var _round:BitmapData;
	
	var _roundDisabled:BitmapData;
	
	var _pointColor:UInt;
	
	var _pointColorDisabled:UInt;
	
	var _topColor:UInt;
	
	var _topAlpha:Float;
	
	public function new(primitives:Primitives = null)
	{
		if (primitives == null)
		{
			primitives = Primitives.defaultPrimitives;
		}
		var isRound = this.isRound();
		_round = primitives.getToggleShape(isRound, true);
		_roundDisabled = primitives.getToggleShape(isRound, false);
		_pointColor = primitives.roundPointColor;
		_pointColorDisabled = primitives.roundPointColorDisabled;
		_topColor = primitives.roundTopColor;
		_topAlpha = primitives.roundTopAlpha;
	}
	
	function isRound()
	{
		return true;
	}
	
	public function create():IFixedButtonSkin
	{
		return new GlamRadioButtonSkin(
			isRound(),
			_round, _roundDisabled, _pointColor, _pointColorDisabled, _topColor, _topAlpha
		);
	}
}

class GlamRadioButtonSkin implements IFixedButtonSkin
{	
	var _top:Shape;
	
	var _point:Shape;
	
	var _bdRound:BitmapData;
	
	var _bdRoundDisabled:BitmapData;
	
	var _bitmap:Bitmap;
	
	var _pointColor:UInt;
	
	var _pointColorDisabled:UInt;
	
	var _isRound:Bool;
	
	public function new(
		isRound:Bool,
		bdRound:BitmapData, bdRoundDisabled:BitmapData, pointColor:UInt, pointColorDisabled:UInt, topColor:UInt, topAlpha:Float
	) 
	{
		_isRound = isRound;
		
		_bdRound = bdRound;
		_bdRoundDisabled = bdRoundDisabled;
		
		_pointColor = pointColor;
		_pointColorDisabled = pointColorDisabled;
		
		var sprite = new Sprite();
		object = sprite;
		
		_bitmap = new Bitmap(bdRound);
		sprite.addChild(_bitmap);
		
		width = bdRound.width;
		height = bdRound.height;
		
		var centerX = width >> 1;
		var centerY = height >> 1;
		
		_top = new Shape();
		_top.x = centerX;
		_top.y = centerY;
		_top.visible = false;
		sprite.addChild(_top);
		
		var g = _top.graphics;
		g.beginFill(topColor, topAlpha);
		if (isRound)
		{
			g.drawCircle(0, 0, (width >> 1) - 4);
		}
		else
		{
			var radius = (width >> 1) - 3;
			g.drawRect(-radius, -radius, radius << 1, radius << 1);
		}
		g.endFill();
		
		_point = new Shape();
		_point.visible = false;
		_point.x = centerX;
		_point.y = centerY;
		sprite.addChild(_point);
		
		_t = 0;
		
		_oldEnabled = null;
	}
	
	var _oldSelected:Bool;
	
	var _oldState:ButtonState;
	
	var _oldEnabled:Null<Bool>;
	
	public function update()
	{
		if (_oldSelected != selected)
		{
			_point.visible = selected;
			_oldSelected = selected;
		}
		if (_oldState != state)
		{
			switch(state)
			{
				case NORMAL, OVER, DISABLED:
					_point.scaleX = _point.scaleY = 1;
				case DOWN:
					if (!selected)
					{
						_point.visible = true;
					}
					_point.scaleX = _point.scaleY = 1.4;
			}
			
			var newEnabled:Bool;
			switch(state)
			{
				case NORMAL:
					_isIn = false;
					object.addEventListener(Event.ENTER_FRAME, onEnterFrame);
					newEnabled = true;
				case OVER:
					_top.visible = true;
					_isIn = true;
					onEnterFrame();
					object.addEventListener(Event.ENTER_FRAME, onEnterFrame);
					newEnabled = true;
				case DOWN:
					newEnabled = true;
				case DISABLED:
					_bitmap.bitmapData = _bdRoundDisabled;
					newEnabled = false;
			}
			if (newEnabled != _oldEnabled)
			{
				_bitmap.bitmapData = newEnabled ? _bdRound : _bdRoundDisabled;
				_oldEnabled = newEnabled;
				
				var g = _point.graphics;
				g.clear();
				g.beginFill(newEnabled ? _pointColor : _pointColorDisabled);
				if (_isRound)
				{
					g.drawCircle(0, 0, 3);
				}
				else
				{
					g.moveTo( -4, -2);
					g.lineTo(-1, 1);
					g.lineTo(4, -4);
					g.lineTo(4, -1);
					g.lineTo(-1, 4);
					g.lineTo( -4, 0);
					g.lineTo( -4, -2);
				}
				g.endFill();
			}
			_oldState = state;
		}
	}
	
	static var ANIMATION_STEP = .35;
	
	var _isIn:Bool;
	
	var _t:Float;
	
	function onEnterFrame(event:Event = null)
	{
		if (_isIn)
		{
			if (_t >= 1)
			{
				_t = 1;
				object.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			_t += ANIMATION_STEP;
		}
		else
		{
			if (_t <= 0)
			{
				_top.visible = false;
				_t = 0;
				object.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}
			_t -= ANIMATION_STEP;
		}
		
		_top.scaleX = _top.scaleY = .5 + .5 * Math.sqrt(_t);
	}
	
	public var object(default, null):InteractiveObject;
	
	public var width(default, null):Int;
	
	public var height(default, null):Int;
	
	public var state:ButtonState;
	
	public var selected:Bool;
}